home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Converters / Convert_TEXT / Source / shared.subproj / MacToNeXTText.m < prev    next >
Text File  |  1995-06-12  |  18KB  |  483 lines

  1. /***********************************************************************\
  2. Common class for converting Mac to NeXT text in all Convert programs
  3. Copyright (C) 1993 David John Burrowes
  4.  
  5. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.
  6.  
  7. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  8.  
  9. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  10.  
  11. The author, David John Burrowes, can be reached at:
  12.     davidjohn@kira.net.netcom.com
  13.     David John Burrowes
  14.     1926 Ivy #10
  15.     San Mateo, CA 94403-1367
  16. \***********************************************************************/
  17.  
  18. /*====================================================================
  19. This is the implementation file for the MacToNeXTText class.  Full documentation for this class can be found in the MacToNeXTText.rtf file.  I will not duplicate all that fine information here.
  20.  
  21. NOTE: You may find that text doesn't line up properly unless you use the New Century Schoolbook Roman typeface, since this was created with it.
  22.  
  23. INFORMATION:
  24.     This is $Revision: 1.2 $ of this file
  25.     It was last modified by $Author: death $ on $Date: 93/04/04 23:44:36 $
  26.      $Log:    MacToNeXTText.m,v $
  27. Revision 1.2  93/04/04  23:44:36  death
  28. Sun Apr  4 23:44:36 PDT 1993
  29.  
  30. Revision 1.1  93/01/10  15:08:03  death
  31. Sun Jan 10 15:08:03 PST 1993
  32.  
  33. ====================================================================*/
  34.  
  35.  
  36. #import "MacToNeXTText.h"
  37. #import <memory.h>    // for memcpy
  38. #include <strings.h>
  39.  
  40.  
  41. @implementation MacToNeXTText
  42.  
  43.  
  44. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  45. //    Routine:        init:
  46. //    Parameters:    none
  47. //    Returns:        self
  48. //    Stores:        none
  49. //    Description:
  50. //        This initalizes the object by filling in the convert array that it uses to
  51. //        dictate most of its character conversions.
  52. //    Bugs:
  53. //        Note that we store a null to indicate any characters that can't be
  54. //        converted directly.  Because of this strategy, the null character must be dealt
  55. //        with in this object, though really it is part of the superclass' territory.
  56. //        other more complex implementations (keep a flag with each array entry
  57. //        to indicate if we can convert to it, or keep integers so one can store more than
  58. //        one of 256 values in an entry  might be used to reimplement this if needed.
  59. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  60. - (Instance) init
  61. {
  62.     Integer    counter;
  63.     //
  64.     [super init];
  65.  
  66.     StrictIM = NO;
  67.     //
  68.     //    Initialize conversion array with whatever our superclass likes to do.
  69.     //
  70.     for (counter = 0; counter < 256; counter++)
  71.         ConvertArray[counter] = [super    ConvertCharacter: (Character) counter];
  72.     //
  73.     //    We view the world as: we are just like whatever our superclass is, except
  74.     //    that we differ for characters 0,  CR, and anything above 128. =)  So,
  75.     //    modify the table to reflect all of this.  (note: indices are essencially mac
  76.     //    character codes, while values we are assigning are NeXT character codes).
  77.     //
  78.     ConvertArray[CARRIAGERETURN] = NEWLINE; // Convert mac CR's to LF's
  79.     ConvertArray[0x11] = NullCharacter;    // (commandsymbol)
  80.     ConvertArray[0x12] = NullCharacter;    // (check)
  81.     ConvertArray[0x13] = NullCharacter;    // (diamond)
  82.     ConvertArray[0x14] = NullCharacter;    // (apple)
  83.  
  84.     ConvertArray[0x80] = 0x85;            // (Adieresis)
  85.     ConvertArray[0x81] = 0x86;            // (Aring)
  86.     ConvertArray[0x82] = 0x87;            // (Ccedilla)
  87.     ConvertArray[0x83] = 0x89;            // (Eacute)
  88.     ConvertArray[0x84] = 0x91;            // (Ntilde)
  89.     ConvertArray[0x85] = 0x96;            // (Odieresis)
  90.     ConvertArray[0x86] = 0x9A;            // (Udieresis)
  91.     ConvertArray[0x87] = 0xD6;            // (aacute)
  92.     ConvertArray[0x88] = 0xD5;            // (agrave)
  93.     ConvertArray[0x89] = 0xD7;            // (acircumflex)
  94.     ConvertArray[0x8A] = 0xD9;            // (adieresis)
  95.     ConvertArray[0x8B] = 0xD8;            // (atilde)
  96.     ConvertArray[0x8C] = 0xDA;            // (aring)
  97.     ConvertArray[0x8D] = 0xDB;            // (ccedilla)
  98.     ConvertArray[0x8E] = 0xDD;            // (eacute)
  99.     ConvertArray[0x8F] = 0xDC;            // (egrave)
  100.     //    0x9X
  101.     ConvertArray[0x90] = 0xDE;            // (ecircumflex)
  102.     ConvertArray[0x91] = 0xDF;            // (dieresis)
  103.     ConvertArray[0x92] = 0xE2;            // (iacute)
  104.     ConvertArray[0x93] = 0xE0;            // (igrave)
  105.     ConvertArray[0x94] = 0xE4;            // (icircumflex)
  106.     ConvertArray[0x95] = 0xE5;            // (idieresis)
  107.     ConvertArray[0x96] = 0xE7;            // (ntilde)
  108.     ConvertArray[0x97] = 0xED;            // (oacute)
  109.     ConvertArray[0x98] = 0xEC;            // (ograve)
  110.     ConvertArray[0x99] = 0xEE;            // (ocircumflex)
  111.     ConvertArray[0x9A] = 0xF0;            // (odieresis)
  112.     ConvertArray[0x9B] = 0xEF;            // (otilde)
  113.     ConvertArray[0x9C] = 0xF3;            // (uacute)
  114.     ConvertArray[0x9D] = 0xF2;            // (ugrave)
  115.     ConvertArray[0x9E] = 0xF4;            // (ucircumflex)
  116.     ConvertArray[0x9F] = 0xF6;            // (udieresis)
  117.     //    0xAX
  118.     ConvertArray[0xA0] = 0xB2;            // (dagger)
  119.     ConvertArray[0xA1] = NullCharacter;    // (degree)
  120.     ConvertArray[0xA2] = 0xA2;            // (cent)
  121.     ConvertArray[0xA3] = 0xA3;            // (sterling)
  122.     ConvertArray[0xA4] = 0xA7;            // (section)
  123.     ConvertArray[0xA5] = 0xB7;            // (bullet)
  124.     ConvertArray[0xA6] = 0xB6;            // (paragraph)
  125.     ConvertArray[0xA7] = 0xFB;            // (germandbls)
  126.     ConvertArray[0xA8] = 0xB0;            // (registerserif)
  127.     ConvertArray[0xA9] = 0xA0;            // (copyrightserif)
  128.     ConvertArray[0xAA] = NullCharacter;    // (trademarkserif)
  129.     ConvertArray[0xAB] = 0xC2;            // (acute)
  130.     ConvertArray[0xAC] = 0xC8;            // (dieresis)
  131.     ConvertArray[0xAD] = NullCharacter;    // (notequal)
  132.     ConvertArray[0xAE] = 0xE1;            // (AE)
  133.     ConvertArray[0xAF] = 0xE9;            // (Oslash)
  134.     //    0xBX
  135.     ConvertArray[0xB0] = NullCharacter;    //(infinity)
  136.     ConvertArray[0xB1] = 0xD1;            // (plusminus)
  137.     ConvertArray[0xB2] = NullCharacter;    // (lessequal)
  138.     ConvertArray[0xB3] = NullCharacter;    // (greaterequal)
  139.     ConvertArray[0xB4] = 0xA5;            // (yen)
  140.     ConvertArray[0xB5] = 0x9D;            // (mu)
  141.     ConvertArray[0xB6] = NullCharacter;    // (partialdiff)
  142.     ConvertArray[0xB7] = NullCharacter;    // (summation)
  143.     ConvertArray[0xB8] = NullCharacter;    // (product) 
  144.     ConvertArray[0xB9] = NullCharacter;    // (pi)
  145.     ConvertArray[0xBA] = NullCharacter;    // (integral)
  146.     ConvertArray[0xBB] = 0xE3;            // (ordfeminine)
  147.     ConvertArray[0xBC] = 0xEB;            // (ordmasculine)
  148.     ConvertArray[0xBD] = NullCharacter;    // (Omega)
  149.     ConvertArray[0xBE] = 0xF1;            // (ae)
  150.     ConvertArray[0xBF] = 0xF9;            // (oslash)
  151.     //    0xC0
  152.     ConvertArray[0xC0] = 0xBF;            // (questiondown)
  153.     ConvertArray[0xC1] = 0xA1;            // (exclamdown)
  154.     ConvertArray[0xC2] = 0xBE;            // (logicalnot)
  155.     ConvertArray[0xC3] = NullCharacter;    // (radical)
  156.     ConvertArray[0xC4] = 0xA6;            // (florin)
  157.     ConvertArray[0xC5] = NullCharacter;    // (approxequal)
  158.     ConvertArray[0xC6] = NullCharacter;    // (delta)
  159.     ConvertArray[0xC7] = 0xAB;            // (guillemotleft)
  160.     ConvertArray[0xC8] = 0xBB;            // (guillemotright)
  161.     ConvertArray[0xC9] = 0xBC;            // (elipsis)
  162.     ConvertArray[0xCA] = 0x80;            // (nbspace)   next calls it: (figsp)
  163.     ConvertArray[0xCB] = 0x81;            // (Agrave)
  164.     ConvertArray[0xCC] = 0x84;            // (Atilde)
  165.     ConvertArray[0xCD] = 0x95;            // (Otilde)
  166.     ConvertArray[0xCE] = 0xEA;            // (OE)
  167.     ConvertArray[0xCF] = 0xFA;            // (oe)
  168.     //    0xD0
  169.     ConvertArray[0xD0] = 0xB1;            // (endash)
  170.     ConvertArray[0xD1] = 0xD0;            // (emdash)
  171.     ConvertArray[0xD2] = 0xAA;            // (quotedblleft)
  172.     ConvertArray[0xD3] = 0xBA;            // (quotedblright)
  173.     ConvertArray[0xD4] = 0x60;            // (quoteleft)
  174.     ConvertArray[0xD5] = 0x27;            // (quoteright)
  175.     ConvertArray[0xD6] = 0x9F;            // (divide)
  176.     ConvertArray[0xD7] = NullCharacter;    // (lozenge)
  177.     ConvertArray[0xD8] = 0xFD;            // (ydieresis)
  178.     ConvertArray[0xD9] = NullCharacter;    // (Ydieresis)  (usually a picture in IM fonts)
  179.     ConvertArray[0xDA] = 0xA4;            // (fraction)
  180.     ConvertArray[0xDB] = 0xA8;            // (currency)
  181.     ConvertArray[0xDC] = 0xAC;            // (guilsinglleft)
  182.     ConvertArray[0xDD] = 0xAD;            // (guilsinglright)
  183.     ConvertArray[0xDE] = 0xAE;            // (fi)
  184.     ConvertArray[0xDF] = 0xAF;            // (fl)
  185.     //    0xE0
  186.     ConvertArray[0xE0] = 0xB3;            // (daggerdbl)
  187.     ConvertArray[0xE1] = 0xB4;            // (periodcentered)
  188.     ConvertArray[0xE2] = 0xB8;            // (quotesinglebase)
  189.     ConvertArray[0xE3] = 0xB9;            // (quotedblbase)
  190.     ConvertArray[0xE4] = 0xBD;            // (perthousand)
  191.     ConvertArray[0xE5] = 0x83;            // (Acircumflex)
  192.     ConvertArray[0xE6] = 0x8A;            // (Ecircumflex)
  193.     ConvertArray[0xE7] = 0x82;            // (Aacute)
  194.     ConvertArray[0xE8] = 0x8B;            // (Edieresis)
  195.     ConvertArray[0xE9] = 0x88;            // (Egrave)
  196.     ConvertArray[0xEA] = 0x8D;            // (Iacute)
  197.     ConvertArray[0xEB] = 0x8E;            // (Icircumflex)
  198.     ConvertArray[0xEC] = 0x8F;            // (Idieresis)
  199.     ConvertArray[0xED] = 0x8C;            // (Igrave)
  200.     ConvertArray[0xEE] = 0x93;            // (Oacute)
  201.     ConvertArray[0xEF] = 0x94;            // (Ocircumflex)
  202.     //    0xF0
  203.     ConvertArray[0xF0] = NullCharacter;    // (apple)
  204.     ConvertArray[0xF1] = 0x92;            // (Ograve)
  205.     ConvertArray[0xF2] = 0x98;            // (Uacute)
  206.     ConvertArray[0xF3] = 0x99;            // (Ucircumflex)
  207.     ConvertArray[0xF4] = 0x97;            // (Ugrave)
  208.     ConvertArray[0xF5] = 0xF5;            // (dotlessi)
  209.     ConvertArray[0xF6] = 0xC3;            // (circumflex)
  210.     ConvertArray[0xF7] = 0xC4;            // (tilde)
  211.     ConvertArray[0xF8] = 0xC5;            // (macron)
  212.     ConvertArray[0xF9] = 0xC6;            // (breve)
  213.     ConvertArray[0xFA] = 0xC7;            // (dotaccent)
  214.     ConvertArray[0xFB] = 0xCA;            // (ring)
  215.     ConvertArray[0xFC] = 0xCB;            // (cedilla)
  216.     ConvertArray[0xFD] = 0xCD;            // (hungarumlaut)
  217.     ConvertArray[0xFE] = 0xCE;            // (ogonek)
  218.     ConvertArray[0xFF] = 0xCF;            // (caron)
  219.     
  220.     return self;
  221. }
  222.  
  223.  
  224.  
  225.  
  226. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  227. //    Routine:        ConvertCharacter:
  228. //    Parameters:    a character to be converted
  229. //    Returns:        the converted character
  230. //    Stores:        the character that we are returning.
  231. //    Description:
  232. //        This uses the ConvertArray set up in the initialization to convert
  233. //        a character from a Mac character set to a NeXT.  It allows for strict
  234. //        adherance to the table in Inside Mac vol 1. p. 221.  It returns the converted
  235. //        character and a result code based on its succes.
  236. //    Bugs:
  237. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  238. - (Character) ConvertCharacter: (Character) theCharacter
  239. {
  240.     Character    result;
  241.     Boolean        couldconvert = YES;
  242.     [self ResetResults];
  243.     //
  244.     //    Determine if we are doing 'strict inside mac vol 1 p. 221' conversions.
  245.     //    if so, and the character is undefind in IM, return character literally.
  246.     //
  247.     if ((theCharacter > 0xD8) && (StrictIM == YES))
  248.         result = theCharacter;
  249.     else
  250.     {
  251.         //
  252.         //    In general, look up our result in the conversion array.  if we get a
  253.         //    null back (and we don't didn't pass a null), indicate we could not
  254.         //    convet properly.
  255.         //
  256.         result = ConvertArray[theCharacter];
  257.         if ((result == NullCharacter) &&  (theCharacter != NullCharacter))
  258.         {
  259.             result = theCharacter;
  260.             couldconvert = NO;
  261.         }
  262.     }
  263.     //
  264.     //    Store the result, and return.
  265.     //
  266.     [self    PutCharacter: result Into: FIRST_RESULT];
  267.     if (couldconvert == YES)
  268.         [self    StoreErrorCode: errOK AndText: "Character converted!"];
  269.     else
  270.         [self    StoreErrorCode: errCANTMAPTOONE AndText: "No equivalent standard NeXTSTEP character"];
  271.     return result;
  272. }
  273.  
  274.  
  275. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  276. //    Routine:        ConvertString:WithLength:
  277. //    Parameters:    a pointer to a string of data to be converted
  278. //                the length of the data the poiner poins to.
  279. //    Returns:        a poiner to a new block of data to be converted
  280. //    Stores:        the pointer we are returning
  281. //                the length of the new data
  282. //    Description:
  283. //        This converts the text in the source data area into a new area.
  284. //        This is passed a string of characters.  This then creates a new string,
  285. //        and converts all the source characters from a Macintosh encoding to
  286. //        the destination string.  This differs from ConvertCharacter:, above, int only
  287. //        two ways:  The first is that this processes multiple characters at once.
  288. //        the second is that if it finds a character that's doens't map to a specific
  289. //        alternate character, it will replace it with a multi character string.  E.g.
  290. //        less  than or equal to is replaced with <=  And the apple symbol is just
  291. //        replaced with [apple].  The source string is not altered in any way.  The
  292. //        caller is responsible for disposing of the returned string.
  293. //    Bugs:
  294. //        we don't really check for errors anywhere (not taht there are many oportunities)...
  295. //    History
  296. //        92.12.31    djb    Added a null-character termination to the string.
  297. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  298. - (Pointer) ConvertString: (Pointer) theData WithLength: (Integer) length
  299. {
  300.     Character*    source = (Character*) theData; // getting a better typed ptr.
  301.     Integer        index,  destindex = 0;
  302.     Integer        destsize = length*1.5;
  303.     Integer        replacelength;
  304.     CString        replacement;
  305.     Character*    temp, *dest = (Character*) NewPointer(destsize);
  306.     Character    result;
  307.     [self    ResetResults];
  308.     //
  309.     for (index = 0; index < length; index++)
  310.     {
  311.         //
  312.         //    Determine if we are doing 'strict inside mac vol 1 p. 221' conversions.
  313.         //    if so, and the character is undefind in IM, return character literally.
  314.         //    Otherwise, just get whatever the standard conversion is.
  315.         //
  316.         if ((source[index] > 0xD8)&&(StrictIM == YES))
  317.             result = source[index];
  318.         else
  319.             result = ConvertArray[source[index]];
  320.         //
  321.         //    If our result is not a null (or if we passed a null), stick the result into
  322.         //    the destination space.  increment the space if necessary.
  323.         //
  324.         if ((result != NullCharacter) ||  (source[index] == NullCharacter))
  325.         {
  326.             if (destindex >= destsize)
  327.             {
  328.                 temp = NewPointer(destsize +512);
  329.                 memcpy(temp, dest, destsize);
  330.                 FreePointer(dest);
  331.                 dest = temp;
  332.                 destsize += 512;
  333.             }
  334.             dest[destindex] = result;
  335.             destindex++;
  336.         }
  337.         else
  338.         {
  339.             //
  340.             //    We evidently got a null back, telling us 'yo! I can't convert this to
  341.             //    a different single character'.  So, now we determine which it was, and
  342.             //    determine what string to use in its place.  Generally, we use the PS
  343.             //    name for the character in []'s.
  344.             //
  345.             switch (source[index])
  346.             {
  347.                 case 0x11:            // (commandsymbol)
  348.                     replacement = "[commandsymbol]";
  349.                     break;
  350.                 case 0x12:            // (check)
  351.                     replacement = "[check]";
  352.                     break;
  353.                 case 0x13:            // (diamond)
  354.                     replacement = "[diamond]";
  355.                     break;
  356.                 case 0x14:            // (apple)
  357.                     replacement = "[apple]";
  358.                     break;
  359.                 case 0xA1:            // (degree)
  360.                     replacement = "[degrees]";
  361.                     break;
  362.                 case 0xAA:            // (trademarkserif)
  363.                     replacement = "[trademarkserif]";
  364.                     break;
  365.                 case 0xAD:            // (notequal)
  366.                     replacement = "<>";
  367.                     break;
  368.                 case 0xB0:            // (infinity)
  369.                     replacement = "[infinity]";
  370.                     break;
  371.                 case 0xB2:            // (lessequal)
  372.                     replacement = "<=";
  373.                     break;
  374.                 case 0xB3:            // (greaterequal)
  375.                     replacement = ">=";
  376.                     break;
  377.                 case 0xB6:            // (partialdiff)
  378.                     replacement = "[partialdiff]";
  379.                     break;
  380.                 case 0xB7:            // (summation)
  381.                     replacement = "[summation]";
  382.                     break;
  383.                 case 0xB8:            // (product) 
  384.                     replacement = "[product]";
  385.                     break;
  386.                 case 0xB9:            // (pi)
  387.                     replacement = "[pi]";
  388.                     break;
  389.                 case 0xBA:            // (integral)
  390.                     replacement = "[integral]";
  391.                     break;
  392.                 case 0xBD:            // (Omega)
  393.                     replacement = "[Omega]";
  394.                     break;
  395.                 case 0xC3:            // (radical)
  396.                     replacement = "[radical]";
  397.                     break;
  398.                 case 0xC5:            // (approxequal)
  399.                     replacement = "[approxequal]";
  400.                     break;
  401.                 case 0xC6:            // (delta)
  402.                     replacement = "[delta]";
  403.                     break;
  404.                 case 0xD7:            // (lozenge)
  405.                     replacement = "[lozenge]";
  406.                     break;
  407.                 case 0xD9:            // (Ydieresis)  (usually a picture in IM fonts)
  408.                     if (StrictIM == NO)
  409.                         replacement = "[Ydieresis(or picture)]";
  410.                     else
  411.                         replacement = "\331"; // the character itself.
  412.                     break;
  413.                 case 0xF0:            // (apple)
  414.                     if (StrictIM == NO)
  415.                         replacement = "[apple]";
  416.                     else
  417.                         replacement = "\360"; // the character itself.
  418.                     break;
  419.                 default:
  420.                     replacement = "[[THERE IS A BUG IN THE PROIGRAM (no joke)]]";
  421.                     break;
  422.             }
  423.             //
  424.             //    With a string in hand to use now, get it's length, and assure that we
  425.             //    have space to store it (if not, increment the memory block's size).
  426.             //    copy the string into the output memory space, and continue.
  427.             //
  428.             replacelength = strlen(replacement);
  429.             if ( (destindex+replacelength) >= destsize)
  430.             {
  431.                 temp = NewPointer(destsize + 512);
  432.                 memcpy(temp, dest, destsize);
  433.                 FreePointer(dest);
  434.                 dest = temp;
  435.                 destsize = destsize + 512;
  436.             }
  437.             memcpy(&dest[destindex], replacement, strlen(replacement));
  438.             destindex += replacelength;
  439.         }
  440.     }
  441.     //
  442.     //    Added, so that the block of memory returned is also null terminated.
  443.     //
  444.     if (destindex >= destsize)
  445.     {
  446.         temp = NewPointer(destsize +512);
  447.         memcpy(temp, dest, destsize);
  448.         FreePointer(dest);
  449.         dest = temp;
  450.         destsize += 512;
  451.     }
  452.     dest[destindex] = EndOfCString;
  453.  
  454.  
  455.     //
  456.     //    Store the result, and return.  (note that destindex always ends up pointing to
  457.     //    the next byte to be used, and thus is also a count of the total number of bytes
  458.     //    in the dest string.
  459.     //
  460.     [self    StorePointer: dest];
  461.     [self    PutPositiveInteger: destindex  Into: SECOND_RESULT];
  462.     [self    StoreErrorCode: errOK AndText: "Nothing could go wrong (pathetic program)!"];
  463.     return dest;
  464. }
  465.  
  466.  
  467. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  468. //    Routine:        UseIMVI:
  469. //    Parameters:    a boolean value
  470. //    Returns:        self
  471. //    Stores:        none
  472. //    Description:
  473. //        This simply allows the user to toggle whether they want to do strict IM
  474. //        conversions.
  475. //    Bugs:
  476. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  477. - UseIM1:  (Boolean) doItStrictly
  478. {
  479.     StrictIM = doItStrictly;
  480.     return self;
  481. }
  482. @end
  483.